
use std::fs::File;
use std::io::ErrorKind;
use std::io;
use std::io::Read;

pub fn test() {
    let res = File::open("hello.txt");
    let f = match res {
        Ok(file) => file,
        Err(err) => match err.kind(){
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(er) => {
                    panic!("新建文件错误：{:?}", er);
                },
            },
            _ =>{
                panic!("文件打开错误：{:?}", err);
            },
        },
    };
}

pub fn read_username() -> Result<String, io::Error> {
    let res = File::open("hello.txt");

    let mut f = match res {
        Ok(file) => file,
        Err(err) => return Err(err),
    };

    let mut name = String::new();
    match f.read_to_string(&mut name) { //NOTE: 这里需要 use std::io::read;
        Ok(_) => return Ok(name),
        Err(e) => return Err(e),
    };

}

pub fn read_username2() -> Result<String, io::Error> {
    // NOTE: ? 通配符 用于错误传递的简写
    // Result 值之后的 ? 被定义为与Result 值的 match 表达式有着完全相同的工作方式。
    // 如果 Result 的值是 Ok，这个表达式将会返回 Ok 中的值而程序将继续执行。
    // 如果值是 Err，Err 中的值将作为整个函数的返回值，就好像使用了 return 关键字一样，这样错误值就被传播给了调用者。
    let mut f = File::open("hello.txt")?;

    let mut name = String::new();

    f.read_to_string(&mut name) ?;

    Ok(name)
}

pub fn read_username3() -> Result<String, io::Error> {
    let mut name = String::new();

    // ? 可以连接
    File::open("hello.txt")?.read_to_string(&mut name)?;

    Ok(name)
}